<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>游戏移植版本</title>
    <style>
        body {
            margin: 0;
            padding: 0;
            background: #000;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            overflow: hidden;
        }
        #gameCanvas {
            border: 2px solid #fff;
            background: #000;
        }
    </style>
</head>
<body>
    <canvas id="gameCanvas" width="1280" height="720"></canvas>

    <script>
        // 常量定义
        const WINDOW_WIDTH = 1280;
        const WINDOW_HEIGHT = 720;
        const PLAYER_WIDTH = 80;
        const PLAYER_HEIGHT = 80;
        const BUTTON_WIDTH = 192;
        const BUTTON_HEIGHT = 75;
        
        // 游戏状态
        let running = true;
        let isGameStart = false;
        let score = 0;
        let lastTime = 0;
        let deltaTime = 0;
        
        // 资源加载
        const resources = {
            images: {},
            sounds: {}
        };

        // 图片资源列表
        const imageSources = [
            // 玩家相关
            { key: 'shadow_player', path: 'img/shadow_player.png' },
            ...Array.from({ length: 6 }, (_, i) => ({ key: `player_left_${i}`, path: `img/player_left_${i}.png` })),
            ...Array.from({ length: 6 }, (_, i) => ({ key: `player_right_${i}`, path: `img/player_right_${i}.png` })),
            
            // 敌人相关
            { key: 'shadow_enemy', path: 'img/shadow_enemy.png' },
            ...Array.from({ length: 6 }, (_, i) => ({ key: `enemy_left_${i}`, path: `img/enemy_left_${i}.png` })),
            ...Array.from({ length: 6 }, (_, i) => ({ key: `enemy_right_${i}`, path: `img/enemy_right_${i}.png` })),
            
            // 界面相关
            { key: 'menu', path: 'img/menu.png' },
            { key: 'background', path: 'img/background.png' },
            { key: 'ui_start_idle', path: 'img/ui_start_idle.png' },
            { key: 'ui_start_hovered', path: 'img/ui_start_hovered.png' },
            { key: 'ui_start_pushed', path: 'img/ui_start_pushed.png' },
            { key: 'ui_quit_idle', path: 'img/ui_quit_idle.png' },
            { key: 'ui_quit_hovered', path: 'img/ui_quit_hovered.png' },
            { key: 'ui_quit_pushed', path: 'img/ui_quit_pushed.png' }
        ];

        // 音频资源列表
        const soundSources = [
            { key: 'bgm', path: 'mus/bgm.mp3' },
            { key: 'hit', path: 'mus/hit.wav' }
        ];

        // 加载图片资源
        function loadImages() {
            return new Promise((resolve) => {
                let loaded = 0;
                imageSources.forEach(({ key, path }) => {
                    const img = new Image();
                    img.src = path;
                    img.onload = () => {
                        resources.images[key] = img;
                        loaded++;
                        if (loaded === imageSources.length) resolve();
                    };
                    // 处理加载失败
                    img.onerror = () => {
                        console.warn(`图片加载失败: ${path}`);
                        loaded++;
                        if (loaded === imageSources.length) resolve();
                    };
                });
            });
        }

        // 加载音频资源
        function loadSounds() {
            return new Promise((resolve) => {
                let loaded = 0;
                soundSources.forEach(({ key, path }) => {
                    const audio = new Audio(path);
                    audio.preload = 'auto';
                    audio.oncanplaythrough = () => {
                        resources.sounds[key] = audio;
                        loaded++;
                        if (loaded === soundSources.length) resolve();
                    };
                    // 处理加载失败
                    audio.onerror = () => {
                        console.warn(`音频加载失败: ${path}`);
                        loaded++;
                        if (loaded === soundSources.length) resolve();
                    };
                });
            });
        }

        // 动画类
        class Animation {
            constructor(prefix, count, interval) {
                this.frameList = [];
                this.intervalMs = interval;
                this.timer = 0;
                this.idxFrame = 0;

                // 收集帧图片
                for (let i = 0; i < count; i++) {
                    this.frameList.push(resources.images[`${prefix}_${i}`]);
                }
            }

            play(ctx, x, y, delta) {
                this.timer += delta;
                if (this.timer >= this.intervalMs) {
                    this.idxFrame = (this.idxFrame + 1) % this.frameList.length;
                    this.timer = 0;
                }
                
                const frame = this.frameList[this.idxFrame];
                if (frame) {
                    ctx.drawImage(frame, x, y);
                }
            }
        }

        // 子弹类
        class Bullet {
            constructor() {
                this.position = { x: 0, y: 0 };
                this.radius = 10;
            }

            draw(ctx) {
                ctx.save();
                ctx.fillStyle = 'rgb(200, 75, 10)';
                ctx.strokeStyle = 'rgb(255, 155, 50)';
                ctx.beginPath();
                ctx.arc(this.position.x, this.position.y, this.radius, 0, Math.PI * 2);
                ctx.fill();
                ctx.stroke();
                ctx.restore();
            }
        }

        // 玩家类
        class Player {
            constructor() {
                this.playerPos = { x: 500, y: 500 };
                this.playerSpeed = 5;
                this.shadowWidth = 32;
                this.moveLeft = false;
                this.moveRight = false;
                this.moveUp = false;
                this.moveDown = false;
                this.facingLeft = false;

                // 加载阴影和动画
                this.imgShadow = resources.images['shadow_player'];
                this.animLeft = new Animation('player_left', 6, 8);
                this.animRight = new Animation('player_right', 6, 8);
            }

            processEvent(event) {
                const isKeyDown = event.type === 'keydown';
                switch (event.key) {
                    case 'ArrowLeft':
                        this.moveLeft = isKeyDown;
                        break;
                    case 'ArrowRight':
                        this.moveRight = isKeyDown;
                        break;
                    case 'ArrowUp':
                        this.moveUp = isKeyDown;
                        break;
                    case 'ArrowDown':
                        this.moveDown = isKeyDown;
                        break;
                }
            }

            move() {
                let dirX = (this.moveRight ? 1 : 0) - (this.moveLeft ? 1 : 0);
                let dirY = (this.moveDown ? 1 : 0) - (this.moveUp ? 1 : 0);
                
                // 归一化方向向量
                const lenDir = Math.sqrt(dirX * dirX + dirY * dirY);
                if (lenDir !== 0) {
                    dirX /= lenDir;
                    dirY /= lenDir;
                    
                    this.playerPos.x += dirX * this.playerSpeed;
                    this.playerPos.y += dirY * this.playerSpeed;
                }

                // 边界检测
                this.playerPos.x = Math.max(0, Math.min(WINDOW_WIDTH - PLAYER_WIDTH, this.playerPos.x));
                this.playerPos.y = Math.max(0, Math.min(WINDOW_HEIGHT - PLAYER_HEIGHT, this.playerPos.y));

                // 更新朝向
                if (dirX < 0) this.facingLeft = true;
                else if (dirX > 0) this.facingLeft = false;
            }

            draw(ctx, delta) {
                // 绘制阴影
                const shadowX = this.playerPos.x + (PLAYER_WIDTH / 2 - this.shadowWidth / 2);
                const shadowY = this.playerPos.y + PLAYER_HEIGHT - 8;
                if (this.imgShadow) {
                    ctx.drawImage(this.imgShadow, shadowX, shadowY);
                }

                // 绘制玩家动画
                if (this.facingLeft) {
                    this.animLeft.play(ctx, this.playerPos.x, this.playerPos.y, delta);
                } else {
                    this.animRight.play(ctx, this.playerPos.x, this.playerPos.y, delta);
                }
            }

            getPosition() {
                return { ...this.playerPos };
            }
        }

        // 敌人类
        class Enemy {
            constructor() {
                this.position = { x: 0, y: 0 };
                this.playerSpeed = 3;
                this.framesWidth = 80;
                this.framesHeight = 80;
                this.shadowWidth = 48;
                this.alive = true;
                this.facingLeft = false;

                // 加载阴影和动画
                this.imgShadow = resources.images['shadow_enemy'];
                this.animLeft = new Animation('enemy_left', 6, 9);
                this.animRight = new Animation('enemy_right', 6, 9);

                // 随机生成位置
                this.spawnRandomly();
            }

            spawnRandomly() {
                const edge = Math.floor(Math.random() * 4); // 0-3 对应四个方向
                switch (edge) {
                    case 0: // 上
                        this.position.x = Math.random() * WINDOW_WIDTH;
                        this.position.y = -this.framesHeight;
                        break;
                    case 1: // 下
                        this.position.x = Math.random() * WINDOW_WIDTH;
                        this.position.y = WINDOW_HEIGHT;
                        break;
                    case 2: // 左
                        this.position.x = -this.framesWidth;
                        this.position.y = Math.random() * WINDOW_HEIGHT;
                        break;
                    case 3: // 右
                        this.position.x = WINDOW_WIDTH;
                        this.position.y = Math.random() * WINDOW_HEIGHT;
                        break;
                }
            }

            checkBulletCollision(bullet) {
                return bullet.position.x >= this.position.x &&
                       bullet.position.x <= this.position.x + this.framesWidth &&
                       bullet.position.y >= this.position.y &&
                       bullet.position.y <= this.position.y + this.framesHeight;
            }

            checkPlayerCollision(player) {
                const playerPos = player.getPosition();
                const checkX = this.position.x + this.framesWidth / 2;
                const checkY = this.position.y + this.framesHeight / 2;
                
                return checkX >= playerPos.x &&
                       checkX <= playerPos.x + PLAYER_WIDTH &&
                       checkY >= playerPos.y &&
                       checkY <= playerPos.y + PLAYER_HEIGHT;
            }

            move(player) {
                const playerPos = player.getPosition();
                let dirX = playerPos.x - this.position.x;
                let dirY = playerPos.y - this.position.y;
                
                const lenDir = Math.sqrt(dirX * dirX + dirY * dirY);
                if (lenDir !== 0) {
                    dirX /= lenDir;
                    dirY /= lenDir;
                    
                    this.position.x += dirX * this.playerSpeed;
                    this.position.y += dirY * this.playerSpeed;
                }

                // 更新朝向
                this.facingLeft = dirX < 0;
            }

            draw(ctx, delta) {
                // 绘制阴影
                const shadowX = this.position.x + (this.framesWidth / 2 - this.shadowWidth / 2);
                const shadowY = this.position.y + this.framesHeight - 35;
                if (this.imgShadow) {
                    ctx.drawImage(this.imgShadow, shadowX, shadowY);
                }

                // 绘制敌人动画
                if (this.facingLeft) {
                    this.animLeft.play(ctx, this.position.x, this.position.y, delta);
                } else {
                    this.animRight.play(ctx, this.position.x, this.position.y, delta);
                }
            }

            hurt() {
                this.alive = false;
            }

            checkAlive() {
                return this.alive;
            }
        }

        // 按钮基类
        class Button {
            constructor(rect, imgIdeaKey, imgHoveredKey, imgPushedKey) {
                this.region = rect;
                this.images = {
                    idea: resources.images[imgIdeaKey],
                    hovered: resources.images[imgHoveredKey],
                    pushed: resources.images[imgPushedKey]
                };
                this.status = 'idea'; // idea, hovered, pushed
            }

            processEvent(event) {
                if (event.type === 'mousemove') {
                    const isHit = this.checkCursorHit(event.clientX, event.clientY);
                    if (this.status === 'idea' && isHit) {
                        this.status = 'hovered';
                    } else if (this.status === 'hovered' && !isHit) {
                        this.status = 'idea';
                    }
                } else if (event.type === 'mousedown' && event.button === 0) {
                    if (this.checkCursorHit(event.clientX, event.clientY)) {
                        this.status = 'pushed';
                    }
                } else if (event.type === 'mouseup' && event.button === 0) {
                    if (this.status === 'pushed') {
                        this.onClick();
                        this.status = 'idea';
                    }
                }
            }

            draw(ctx) {
                const img = this.images[this.status];
                if (img) {
                    ctx.drawImage(img, this.region.left, this.region.top);
                }
            }

            checkCursorHit(x, y) {
                const rect = this.region;
                return x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom;
            }

            onClick() {
                // 子类实现
            }
        }

        // 开始游戏按钮
        class StartGameButton extends Button {
            constructor(rect) {
                super(rect, 'ui_start_idle', 'ui_start_hovered', 'ui_start_pushed');
            }

            onClick() {
                isGameStart = true;
                // 播放背景音乐
                const bgm = resources.sounds.bgm;
                if (bgm) {
                    bgm.loop = true;
                    bgm.play().catch(err => console.warn('播放BGM失败:', err));
                }
            }
        }

        // 退出游戏按钮
        class QuitGameButton extends Button {
            constructor(rect) {
                super(rect, 'ui_quit_idle', 'ui_quit_hovered', 'ui_quit_pushed');
            }

            onClick() {
                running = false;
            }
        }

        // 游戏主函数
        async function initGame() {
            const canvas = document.getElementById('gameCanvas');
            const ctx = canvas.getContext('2d');

            // 加载资源
            await Promise.all([loadImages(), loadSounds()]);

            // 初始化游戏对象
            const player = new Player();
            const bulletList = [new Bullet(), new Bullet(), new Bullet()];
            const enemyList = [];

            // 创建按钮
            const regionBtnStart = {
                left: (WINDOW_WIDTH - BUTTON_WIDTH) / 2,
                right: (WINDOW_WIDTH - BUTTON_WIDTH) / 2 + BUTTON_WIDTH,
                top: 430,
                bottom: 430 + BUTTON_HEIGHT
            };
            const regionBtnQuit = {
                left: (WINDOW_WIDTH - BUTTON_WIDTH) / 2,
                right: (WINDOW_WIDTH - BUTTON_WIDTH) / 2 + BUTTON_WIDTH,
                top: 550,
                bottom: 550 + BUTTON_HEIGHT
            };

            const btnStart = new StartGameButton(regionBtnStart);
            const btnQuit = new QuitGameButton(regionBtnQuit);

            // 图片资源
            const imgMenu = resources.images.menu;
            const imgBackground = resources.images.background;

            // 生成敌人
            function tryGenerateEnemy() {
                const INTERVAL = 100;
                static let counter = 0;
                if ((++counter) % INTERVAL === 0) {
                    enemyList.push(new Enemy());
                }
            }

            // 更新子弹
            function updateBullets() {
                const RADIAL_SPEED = 0.0045;
                const TANGENT_SPEED = 0.0020;
                const playerPos = player.getPosition();
                const radius = 100 + 25 * Math.sin(Date.now() * RADIAL_SPEED);
                const radianInterval = (2 * Math.PI) / bulletList.length;

                bulletList.forEach((bullet, i) => {
                    const radian = Date.now() * TANGENT_SPEED + radianInterval * i;
                    bullet.position.x = playerPos.x + PLAYER_WIDTH / 2 + radius * Math.sin(radian);
                    bullet.position.y = playerPos.y + PLAYER_HEIGHT / 2 + radius * Math.cos(radian);
                });
            }

            // 绘制分数
            function drawPlayerScore() {
                ctx.save();
                ctx.fillStyle = 'rgb(255, 85, 185)';
                ctx.font = '24px Arial';
                ctx.fillText(`当前分数: ${score}`, 10, 30);
                ctx.restore();
            }

            // 事件监听
            window.addEventListener('keydown', (e) => {
                if (isGameStart) {
                    player.processEvent(e);
                }
            });

            window.addEventListener('keyup', (e) => {
                if (isGameStart) {
                    player.processEvent(e);
                }
            });

            window.addEventListener('mousemove', (e) => {
                if (!isGameStart) {
                    btnStart.processEvent(e);
                    btnQuit.processEvent(e);
                }
            });

            window.addEventListener('mousedown', (e) => {
                if (!isGameStart) {
                    btnStart.processEvent(e);
                    btnQuit.processEvent(e);
                }
            });

            window.addEventListener('mouseup', (e) => {
                if (!isGameStart) {
                    btnStart.processEvent(e);
                    btnQuit.processEvent(e);
                }
            });

            // 游戏主循环
            function gameLoop(timestamp) {
                if (!running) return;
                
                // 计算时间差
                deltaTime = timestamp - lastTime || 0;
                lastTime = timestamp;

                // 清空画布
                ctx.clearRect(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);

                if (isGameStart) {
                    // 游戏逻辑更新
                    player.move();
                    updateBullets();
                    tryGenerateEnemy();

                    // 敌人移动
                    enemyList.forEach(enemy => enemy.move(player));

                    // 碰撞检测 - 玩家与敌人
                    for (const enemy of enemyList) {
                        if (enemy.checkPlayerCollision(player)) {
                            alert('游戏结束：被敌人击中！');
                            running = false;
                            return;
                        }
                    }

                    // 碰撞检测 - 子弹与敌人
                    for (const enemy of enemyList) {
                        for (const bullet of bulletList) {
                            if (enemy.checkBulletCollision(bullet)) {
                                // 播放击中音效
                                const hitSound = resources.sounds.hit;
                                if (hitSound) {
                                    hitSound.currentTime = 0;
                                    hitSound.play().catch(err => console.warn('播放击中音效失败:', err));
                                }
                                enemy.hurt();
                                score++;
                            }
                        }
                    }

                    // 移除死亡的敌人
                    for (let i = enemyList.length - 1; i >= 0; i--) {
                        if (!enemyList[i].checkAlive()) {
                            enemyList.splice(i, 1);
                        }
                    }

                    // 绘制游戏元素
                    if (imgBackground) {
                        ctx.drawImage(imgBackground, 0, 0);
                    }
                    player.draw(ctx, deltaTime);
                    enemyList.forEach(enemy => enemy.draw(ctx, deltaTime));
                    bulletList.forEach(bullet => bullet.draw(ctx));
                    drawPlayerScore();
                } else {
                    // 绘制菜单
                    if (imgMenu) {
                        ctx.drawImage(imgMenu, 0, 0);
                    }
                    btnStart.draw(ctx);
                    btnQuit.draw(ctx);
                }

                requestAnimationFrame(gameLoop);
            }

            // 启动游戏循环
            requestAnimationFrame(gameLoop);
        }

        // 启动游戏
        initGame();
    </script>
</body>
</html>